﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using System.Diagnostics;

using chad.performancecounters.library;

namespace chad.performancecounters.console
{
    class Program
    {
        protected static void DisplayHelp()
        {
            Console.WriteLine("USAGE:");
            Console.WriteLine("     " + System.Diagnostics.Process.GetCurrentProcess().ProcessName);
            Console.WriteLine("          [?]");
            Console.WriteLine("          [ComputerName={ComputerName}]");
            Console.WriteLine("          [OutputPath={OutputPath}]");
            Console.WriteLine("          [OutputType={CSV|XLSX}]");
            Console.WriteLine("");
            Console.WriteLine("   Options");
            Console.WriteLine("     ComputerName - Default=. - The name of the computer to scan");
            Console.WriteLine("     OutputPath - No Default - The folder were to store the output file");
            Console.WriteLine("     OutputType - CSV|XLSX - Default=XLSX - The output file type");
            Console.WriteLine("");
            Console.WriteLine("   Examples");
            Console.WriteLine("     " + System.Diagnostics.Process.GetCurrentProcess().ProcessName + @" OutputPath=c:\temp");
            Console.WriteLine("     " + System.Diagnostics.Process.GetCurrentProcess().ProcessName + @" OutputPath=c:\temp OutputType=CSV");
            Console.WriteLine("     " + System.Diagnostics.Process.GetCurrentProcess().ProcessName + @" OutputPath=c:\temp OutputType=CSV ComputeName=COMPUTERNAME");
        }

        static void Main(string[] args)
        {
            //DEBUG
            /*
            args = new String[] { 
                            "ComputerName=.",
                            //@"OutputFile=c:\Scratch\all_counters.xlsx",
                            @"OutputPath=c:\Scratch\",
                            "OutputType=XLSX" 
                        };
             * */
            Stopwatch watch = new Stopwatch();
            watch.Start();

            const String VARIABLE_NAME_MACHINENAME = "ComputerName";
            const String VARIABLE_NAME_OUTPUTFILE = "OutputFile";
            const String VARIABLE_NAME_OUTPUTPATH = "OutputPath";
            const String VARIABLE_NAME_FILETYPE = "OutputType";

            const String VARIABLE_DEFAULT_FILETYPE = "XLSX";

            /*
            String machineName = ".";
            String fileOutputNameAndPath = @"c:\Scratch\all_counters.csv";
             */

            String machineName = ".";
            String fileOutputNameAndPath = String.Empty;
            String fileOutputPath = String.Empty;
            String fileType = String.Empty;

            // Read and Process Arguments
            foreach(String a in args)
            {
                if(a == "?")
                {
                    DisplayHelp();
                    Environment.Exit(1);
                } 
                else if(a.Contains(VARIABLE_NAME_MACHINENAME + "="))
                {
                    machineName = a.Split(new String[] { VARIABLE_NAME_MACHINENAME + "=" }, StringSplitOptions.RemoveEmptyEntries)[0].Trim();
                } 
                else if (a.Contains(VARIABLE_NAME_OUTPUTFILE +"="))
                {
                    fileOutputNameAndPath = a.Split(new String[] { VARIABLE_NAME_OUTPUTFILE+"=" }, StringSplitOptions.RemoveEmptyEntries)[0].Trim();
                }
                else if (a.Contains(VARIABLE_NAME_FILETYPE + "="))
                {
                    fileType = a.Split(new String[] { VARIABLE_NAME_FILETYPE + "=" }, StringSplitOptions.RemoveEmptyEntries)[0].Trim();
                }
                else if (a.Contains(VARIABLE_NAME_OUTPUTPATH + "="))
                {
                    fileOutputPath = a.Split(new String[] { VARIABLE_NAME_OUTPUTPATH + "=" }, StringSplitOptions.RemoveEmptyEntries)[0].Trim();
                }

            }

            if (String.IsNullOrWhiteSpace(fileType))
            {
                fileType = VARIABLE_DEFAULT_FILETYPE;
            }
            if (fileOutputPath != String.Empty)
            {
                fileOutputNameAndPath = String.Format(@"{0}\{1}.{2}", fileOutputPath, String.Format("{0}_{1}", ((machineName==".") ? Environment.MachineName : machineName), DateTime.Now.ToString("yyyymmddHmmss")), fileType.ToLower());
            }
            if(String.IsNullOrWhiteSpace(fileOutputNameAndPath))
            {
                Logger.WriteError("Missing paramter: OutputPath");
                Logger.WriteInformation("");
                DisplayHelp();
                Environment.Exit(1);
            }

            // Verify File can be created
            if(!WriterHelper.CanCreateFile(fileOutputNameAndPath))
            {
                // Unable to write file
                Logger.WriteError(String.Format("Failed to create the file '{0}'.", fileOutputNameAndPath));
                Environment.Exit(-1);
            }
            
            // Verify that computer can be connected to
            try
            {
                PerformanceCounterHelper.CanConnectToComputer(machineName);
            }catch (Exception ex)
            {
                Logger.WriteError(String.Format("Failed to connect to '{0}' with the message:",machineName));
                Logger.WriteError("     " + ex.Message);
                Logger.WriteInformation("");
                DisplayHelp();
                Environment.Exit(1);
            }

            // Collect Performance Counters 
            PerformanceCounterItem[] counters = PerformanceCounterHelper.GetAllPerformanceCountersOnMachine(machineName);
            // Write to csv
            switch(fileType.ToUpper())
            { 
                case "CSV":
                    WriterHelper.WriteCsvToFileSystem(fileOutputNameAndPath, counters);
                    break;
                case "XLSX":
                    WriterHelper.WriteExcelToFileSystem(fileOutputNameAndPath, counters, machineName);
                    break;
            }

            watch.Stop();

            Logger.WriteInformation(String.Format("Completed processing of '{0}' in {1} seconds",machineName,watch.Elapsed.TotalSeconds));
            
        }
    }
}
